package com.test.util.datasource;


import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.SQLException;

import com.test.bean.BaseConnectionInfo;
import org.apache.tomcat.jdbc.pool.DataSource;
import org.apache.tomcat.jdbc.pool.PoolProperties;
import org.slf4j.LoggerFactory;

import java.util.logging.Logger;

/**
 * @Description
 * @auther Lelouch
 * @create 2018-12-26  10:01
 */
public class DynamicDataSource extends DataSource {
    private static org.slf4j.Logger logger = LoggerFactory.getLogger(DynamicDataSource.class);

    private Object defaultTargetDataSource;

    public void setDefaultTargetDataSource(Object defaultTargetDataSource) {
        this.defaultTargetDataSource = defaultTargetDataSource;
    }

    @Override
    public Connection getConnection() throws SQLException {
        String projectCode = DBIdentifier.getProjectCode();
        //1、获取数据源
        DataSource dds = DDSHolder.instance().getDDS(projectCode);
        //2、如果数据源不存在则创建
        if (dds == null) {
            try {
                DataSource newDDS = initDDS(projectCode);
                DDSHolder.instance().addDDS(projectCode, newDDS);
            } catch (IllegalArgumentException | IllegalAccessException e) {
                logger.error("Init data source fail. projectCode:" + projectCode);
                return null;
            }
        }
        dds = DDSHolder.instance().getDDS(projectCode);
        try {
            return dds.getConnection();
        } catch (SQLException e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 以当前数据对象作为模板复制一份。
     *
     * @return dds
     * @throws IllegalAccessException
     * @throws IllegalArgumentException
     */
    private DataSource initDDS(String projectCode) throws IllegalArgumentException, IllegalAccessException {
        DataSource dds = new DataSource();
        // 2、复制PoolConfiguration的属性
        PoolProperties property = new PoolProperties();
        Field[] pfields = PoolProperties.class.getDeclaredFields();
        for (Field f : pfields) {
            f.setAccessible(true);
            Object value = f.get(this.getPoolProperties());
            try {
                f.set(property, value);
            } catch (Exception e) {
                logger.info("Set value fail. attr name:" + f.getName());
                continue;
            }
        }
        dds.setPoolProperties(property);
        // 3、设置数据库名称和IP(一般来说，端口和用户名、密码都是统一固定的)
        String urlFormat = this.getUrl();
        if(null != projectCode && !"".equals(projectCode)) {
            BaseConnectionInfo baseConnectionInfo = ProjectDBMgr.getConnectionInfo(projectCode);
            if(null != baseConnectionInfo) {
                String driver = baseConnectionInfo.getDriver();
                String url = baseConnectionInfo.getUrl();
                String name = baseConnectionInfo.getName();
                String password = baseConnectionInfo.getPassword();
                if(null != driver && null != url && null != name && null != password) {
                    dds.setDriverClassName(driver);
                    dds.setUrl(url);
                    dds.setName(name);
                    dds.setPassword(password);
                }
            }else {//如果传入了project参数，但是不传入连接信息，那么表示查询的是datasource02的数据源
                return (DataSource)this.defaultTargetDataSource;
            }
           /* String url = String.format(urlFormat, .getDBIP(projectCode),
                    ProjectDBMgr.instance().getDBName(projectCode));*/
            //dds.setUrl(url);
        }
        return dds;
    }

}
